﻿using PLC.Interface.Devices;
using PLC.Interface.Stations;
using PLCWpfTest.Common;
using PLCWpfTest.Common.Extensions;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using YWM.Dto;

namespace PLCWpfTest.ViewModels
{
    public class ParameterSettingViewModel : OperationViewModel, IDisposable
    {
        private readonly IDeviceAppService _deviceAppService;

        private readonly Timer _timer;

        private DeviceDto _device = new DeviceDto();

        public DeviceDto Device
        {
            get
            {
                return _device;
            }
            set { SetProperty(ref _device, value); }
        }

        private IReadOnlyList<StationResultDto> _stations;
        public IReadOnlyList<StationResultDto> Stations
        {
            get { return _stations; }
            set { SetProperty(ref _stations, value); }
        }

        public ParameterSettingViewModel(IDeviceAppService deviceAppService)
        {
            _deviceAppService = deviceAppService;
            Stations = DataCache.Stations;
            _timer = new Timer((state) =>
            {
                UpdateStations();
            }, null, 0, 1000);
        }

        protected override async Task LoadCommand_Executing(object parameter)
        {
            Device = await _deviceAppService.Get();
        }

        private void UpdateStations()
        {
            if (!CommunicationCache.Connected)
            {
                return;
            }
            IReadOnlyList<StationResultDto> stations = new List<StationResultDto>(Stations);
            foreach (StationResultDto item in stations)
            {
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.TempHighLimitId))
                {
                    item.StationVariable.TempHighLimitValue = CommunicationCache.LongVariablePairs[item.StationVariable.TempHighLimitId].Value.ToDouble();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.TempHighId))
                {
                    item.StationVariable.TempHighValue = CommunicationCache.LongVariablePairs[item.StationVariable.TempHighId].Value.ToBoolean();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.TempLowLimitId))
                {
                    item.StationVariable.TempLowLimitValue = CommunicationCache.LongVariablePairs[item.StationVariable.TempLowLimitId].Value.ToDouble();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.TempLowId))
                {
                    item.StationVariable.TempLowValue = CommunicationCache.LongVariablePairs[item.StationVariable.TempLowId].Value.ToBoolean();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.HumidityHighLimitId))
                {
                    item.StationVariable.HumidityHighLimitValue = CommunicationCache.LongVariablePairs[item.StationVariable.HumidityHighLimitId].Value.ToDouble();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.HumidityHighId))
                {
                    item.StationVariable.HumidityHighValue = CommunicationCache.LongVariablePairs[item.StationVariable.HumidityHighId].Value.ToBoolean();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.HumidityLowLimitId))
                {
                    item.StationVariable.HumidityLowLimitValue = CommunicationCache.LongVariablePairs[item.StationVariable.HumidityLowLimitId].Value.ToDouble();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.HumidityLowId))
                {
                    item.StationVariable.HumidityLowValue = CommunicationCache.LongVariablePairs[item.StationVariable.HumidityLowId].Value.ToBoolean();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.TempAlarmEnableId))
                {
                    item.StationVariable.TempAlarmEnableValue = CommunicationCache.LongVariablePairs[item.StationVariable.TempAlarmEnableId].Value.ToShort();
                }
                if (CommunicationCache.LongVariablePairs.ContainsKey(item.StationVariable.HumidityAlarmEnableId))
                {
                    item.StationVariable.HumidityAlarmEnableValue = CommunicationCache.LongVariablePairs[item.StationVariable.HumidityAlarmEnableId].Value.ToShort();
                }
            }
            Stations = stations;
        }

        protected override bool OkCommand_BeforeCanExecute(object parameter)
        {
            return Device.IsValidated;
        }

        protected override async Task<IEntityDto> OkAsync(object parameter)
        {
            await _deviceAppService.Save(Device);
            InitializeCommunication();
            return Device;
        }

        private void InitializeCommunication()
        {
            MessageBoxResult result = this.ShowQuestion("确定重连设备吗");
            if (result == MessageBoxResult.OK)
            {
                CommunicationCache.Uninitialize();
                CommunicationCache.Device = Device;
                CommunicationCache.Initialize();
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
            }
            _timer.Dispose();
        }

        ~ParameterSettingViewModel()
        {
            Dispose(false);
        }
    }
}
